const cp = require('child_process');
const fs = require('fs');
const {
    week, month, date, colors,
    plate: ori_plate, shape,
} = require('./data.json');

function init(plate) {
    // 遍历棋盘与拼图，寻找每个拼图的所有放置可能性，构建每种可能性放置后的棋盘队列
    const shapeNames = Object.keys(shape);
    const res = {};

    for (const shapeName of shapeNames) {
        let i = -1;
        res[shapeName] = [];

        while(i < 7) {
            i++;
            let j = -1;

            while(j < 6) {
                j++;
                let k = -1;

                while (k < shape[shapeName].length - 1) {
                    k++;
                    const shapeItem = shape[shapeName][k];
                    const newPlate = setShape(i, j, plate, shapeItem, shapeName);
                    if (!newPlate) continue;

                    res[shapeName].push({
                        plate: newPlate,
                        path: { i, j, k, name: shapeName },
                    });
                }
            }
        }
    }

    return res;
}

function setShape(i, j, plate, item, name) {
    // 拼图形状以传递坐标起始是否可摆放，是返回摆放后棋盘占位
    const copyPlate = JSON.parse(JSON.stringify(plate));

    const row = item.length - 1;
    const col = item[0].length - 1;

    let rowIndex = -1;
    while(rowIndex < row) {
        rowIndex++;
        let colIndex = -1;

        while(colIndex < col) {
            colIndex++;
            const cell = item[rowIndex][colIndex];
            if (cell === 0) continue;

            const x = i + rowIndex;
            const y = j + colIndex;

            // 越界判断
            if (x >= 8 || y >= 7) return false;
            // 不能放置判断
            if (copyPlate[y][x] === 1) return false;

            copyPlate[y][x] = 1;
        }
    }

    return copyPlate;
}

function fill(num, type, plate) {
    const arr = ({ week, month, date })[type];
    if (!arr) throw new Error('fill params type Exception');

    const val = arr[num - 1];
    const max = plate[0].length;

    const row = Math.floor(val / max);
    const col = val % max;

    if (typeof plate[row][col] !== 'number') {
        throw new Error('fill params num Exception');
    }
    if (plate[row][col] !== 0) {
        throw new Error('fill params num has been assigned a value ');
    }

    plate[row][col] = 1;
};

function main() {
    const DATE = [5, 7, 6];

    const t = Date.now();
    const plate = ori_plate;

    fill(DATE[0], 'month', plate);
    fill(DATE[1], 'date', plate);
    fill(DATE[2], 'week', plate);
    // fs.writeFileSync('./_plate.json', JSON.stringify(plate), 'utf8');

    const shapes = init(plate);
    console.log(Object.keys(shapes).map(k => `${k}: ${shapes[k].length}`).join('\n'));
    console.log('计算拼图摆放可能性耗时: ', (Date.now() - t), 'ms');
}

main();